package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/neo4j/neo4j-go-driver/v4/neo4j"
	"go.uber.org/zap"
	dri "neo4j-go-demo/internal/driver"
	"neo4j-go-demo/internal/item"
	"neo4j-go-demo/internal/token"
	"neo4j-go-demo/setting"
)

func main() {

	r := gin.Default()
	logger := zap.NewNop()
	driver, err := dri.NewDriver(logger, setting.Conf.Neo4j.Uri, setting.Conf.Neo4j.Username, setting.Conf.Neo4j.Password, "")
	//driver, err := neo4j.NewDriver(setting.Conf.Neo4j.Uri, neo4j.BasicAuth(setting.Conf.Neo4j.Username, setting.Conf.Neo4j.Password, ""))
	if err != nil {
		logger.Error("connect neo4j client err")
		return
	}
	defer driver.Close()

	tokenService := token.NewTokenService(*logger)
	tokenController := token.NewTokenController(tokenService, *logger)
	tokenController.Register(r)

	itemService := item.NewItemService(*logger, *driver)
	itemController := item.NewItemController(*logger, itemService)
	itemController.Register(r)

	_ = r.Run(":8081")

	err = setting.Init()
	if err != nil {
		fmt.Printf("init setting failed,err:%s", err.Error())
		return
	}

	//item, err := insertItem(driver)
	insert, err := driver.Do(createItemFn)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v\n", insert.(*Item))

}

func insertItem(driver neo4j.Driver) (*Item, error) {
	session := driver.NewSession(neo4j.SessionConfig{})
	defer session.Close()

	result, err := session.WriteTransaction(createItemFn)
	if err != nil {
		return nil, err
	}
	return result.(*Item), nil
}

func createItemFn(tx neo4j.Transaction) (interface{}, error) {
	records, err := tx.Run("CREATE (n:Item { id: $id, name: $name }) RETURN n.id, n.name", map[string]interface{}{
		"id":   1,
		"name": "Item 1",
	})
	if err != nil {
		return nil, err
	}
	record, err := records.Single()
	if err != nil {
		return nil, err
	}
	// You can also retrieve values by name, with e.g. `id, found := record.Get("n.id")`
	return &Item{
		Id:   record.Values[0].(int64),
		Name: record.Values[1].(string),
	}, nil
}

type Item struct {
	Id   int64
	Name string
}
